'''
Created on Jan 7, 2010

@author: Roni
'''

import os
import sys
import logging
import webgraphs.utils
import cliques.bronKerbosch

RESOURCE_WEBGRAPH_DIR= "../resources/graphs/web/300"
RESOURCE_RESULTS_DIR = "../resources/results"

def load_graphs(graph_dir):
    ''' 
    Load the webgraphs from the files in the given directory
    Returns a dictionary of graph file to graph object 
    '''
    graph_file_names = os.listdir(graph_dir)
    graphs = dict()
    for file in graph_file_names:    
        logging.info("Loading graph %s" % file)
        a_graph = cliques.utils.import_graph(graph_dir + "/" + file,'dot')
        graphs[file]=a_graph
    return graphs
    
def main():
    ''' 
    Gathers descriptive statistics on the webgraphs. This includes the number of nodes, edges, degree distribution 
    and number of cliques.
    '''
    logging.basicConfig(level=logging.DEBUG)
    logging.root.addHandler(logging.StreamHandler(sys.stdout))    
    
    graphs = load_graphs(RESOURCE_WEBGRAPH_DIR)
    all_clique_finder = cliques.bronKerbosch.bronKerboschCliqueFinder()    
    min_degree = 100
    max_degree = 0
    min_clique = 100
    max_clique = 0
    all_stats = []
    print "-------------------Gathering Stats -----------------------------" 
    for graph_file in graphs.keys():
        print "----------------------- %s -------------------------" % graph_file   
        graph_data = graphs[graph_file]
        stats = dict()
        nodes = graph_data.nodes()
        stats['name'] = graph_file
        stats['nodes'] = len(nodes)
        stats['edges'] = len(graph_data.edges())
        
        # Calculate degree histogram
        degree_to_freq = dict()
        for node in nodes:
            degree = graph_data.order(node)
            if degree<min_degree:
                min_degree=degree
            if degree>max_degree:
                max_degree=degree
            if degree_to_freq.has_key(degree):
                degree_to_freq[degree]=degree_to_freq[degree]+1
            else:
                degree_to_freq[degree]=1
        stats['node_degree_hist'] = degree_to_freq


        # Find all the maximal cliques, write to a file and create hist
        all_clique_finder.find(graph_data)     
        out_file = open('%s/all-cliques-%s.txt' % (RESOURCE_RESULTS_DIR,graph_file),'w')
        size_to_freq = dict()   
        for clique in all_clique_finder.cliques:
            clique_size = len(clique)
            if clique_size>max_clique:
                max_clique = clique_size
            if clique_size<min_clique:
                min_clique = clique_size
            if size_to_freq.has_key(clique_size):
                size_to_freq[clique_size]=size_to_freq[clique_size]+1
            else:
                size_to_freq[clique_size]=1
            out_file.write("%d\t%s\n" % (len(clique),clique))
        out_file.close()
        
        stats['clique_size_hist'] = size_to_freq
        all_stats.append(stats)
    
    print "-------------------Printing Stats to File -------------------" 
    out_file = open('%s/stats.txt' % RESOURCE_RESULTS_DIR,'w')
    header = "File    Nodes    Edges    "
    for clique_size in xrange(max_clique,min_clique-1,-1):
        header = header + "    %d-C" % clique_size
    for node_degree in xrange(max_degree,min_degree-1,-1):
        header = header + "    D-%d" % node_degree
    header = header+"\n"
    out_file.write(header)
    for stats in all_stats:
        out_file.write("%s    " % stats['name'])
        out_file.write("%s    " % stats['nodes'])
        out_file.write("%s    " % stats['edges'])
        clique_size_hist = stats['clique_size_hist']       
        for clique_size in xrange(max_clique,min_clique-1,-1):
            if clique_size_hist.has_key(clique_size):
                frequency = clique_size_hist[clique_size]
            else:
                frequency = 0 
            out_file.write("%d    " % frequency)
        
        node_degree_hist = stats['node_degree_hist']
        for node_degree in xrange(max_degree,min_degree-1,-1):
            if node_degree_hist.has_key(node_degree):
                frequency = node_degree_hist[node_degree]
            else:
                frequency = 0
            out_file.write("%d    " % frequency)
        out_file.write("\n")
                 
        

if __name__ == '__main__':
    main()